package com.acme.bankapp.domain;

import java.util.ArrayList;

import com.acme.bankapp.service.listeners.ClientRegistrationListener;

/**
 * 
 * Holds Clients and provides access to them.
 *
 */
public class Bank {
	
	ArrayList<Client> clients;
	ArrayList<ClientRegistrationListener> clientRegistrationListeners; 
	
	/**
	 * Creates Bank with no clients and a debug listener.
	 */
	public Bank() {
		clients = new ArrayList<Client>();
		clientRegistrationListeners = new ArrayList<ClientRegistrationListener>(); 
		clientRegistrationListeners.add(new DebugListener());
	}
	
	/**
	 * Creates Bank with no clients.
	 */
	public Bank(ClientRegistrationListener listener) {
		clients = new ArrayList<Client>();
		clientRegistrationListeners = new ArrayList<ClientRegistrationListener>(); 
		clientRegistrationListeners.add(listener);
	}
	
	/**
	 * Adds the specified Client object with specified initial balance.
	 * Polls listeners.  
	 * @param client Client object to be added.
	 * @param initialBalance Initial balance.
	 * @return client, if it was added, null otherwise. 
	 */
	public Client addClient(Client client, double... initialBalance) {
		if (getClientByName(client.getName()) == null) {
			if (initialBalance != null) {
				client.getAccount().deposit(initialBalance[0]);
			}
	
			clients.add(client);
			
			for (ClientRegistrationListener listener : clientRegistrationListeners) {
				listener.onClientAdded(client);
			}
			
			return client;
		}
		
		for (ClientRegistrationListener listener : clientRegistrationListeners) {
			listener.onClientNotAdded("Client " + client.getName() + " already exists.");
		}
		return null;
	}

	/**
	 * Returns a reference to the internal list of clients.
	 * @return ArrayList(Client)
	 */
	public ArrayList<Client> getClients() {
		return clients;	
	}
	
	/**
	 * Selects a Client with the specified name from all Clients.
	 * @param clientName - Name of the desired client. 
	 * @return Client object if such a client is present; null otherwise.
	 */
	public Client getClientByName(String clientName) {
		for (Client client : clients) {
			if (client.getName() == clientName) {
				return client; 
			}
		}
		
		return null;
	}
	
	/**
	 * Debug output generator for add client actions.
	 */
	private class DebugListener implements ClientRegistrationListener {
		public void onClientAdded(Client client) {
			System.out.println("\n--- Adding client:");
			System.out.println(client + " " + (new java.util.Date()).toString().substring(11, 20));
		}
		
		public void onClientNotAdded(String message) {
			System.out.println("\n--- Adding client...");
			System.out.println("Error: " + message);
		}
	}
}
